/**
 * Copyright (c) 2004-2015 All Rights Reserved.
 */
package com.zbest.component.session;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.codec.digest.DigestUtils;

/**
 * sessionId生成器
 *
 * @author czhou3306@gmail.com
 * @version $Id: SessionIdGenerator.java, v0.1 2015年6月10日 上午11:37:33 czhou3306@gmail.com Exp $
 */
public class SessionIdGenerator {

    private static String        IP_16 = "ffffffff";

    private static AtomicInteger count = new AtomicInteger(1000);

    static {
        try {
            String ipAddress = getInetAddress();
            if (ipAddress != null) {
                IP_16 = getIP_16(ipAddress);
            }
        } catch (Throwable e) {
            /**
             * empty catch block
             */
        }
    }

    /**
     * 获取一个唯一的sessionId
     * 
     * @return
     */
    public static String generate() {
        return getUniqueId(IP_16, System.currentTimeMillis(), getNextId());
    }

    private static String getUniqueId(String ip, long timestamp, int nextId) {
        StringBuilder appender = new StringBuilder(25);
        appender.append(ip).append(timestamp).append(nextId);
        String srUniqueId = appender.toString();
        return DigestUtils.md5Hex(srUniqueId);
    }

    private static String getIP_16(String ip) {
        String[] ips = ip.split("\\.");
        StringBuilder sb = new StringBuilder();
        for (String column : ips) {
            String hex = Integer.toHexString(Integer.parseInt(column));
            if (hex.length() == 1) {
                sb.append('0').append(hex);
            } else {
                sb.append(hex);
            }

        }
        return sb.toString();
    }

    private static String getInetAddress() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress address = null;
            while (interfaces.hasMoreElements()) {
                NetworkInterface ni = interfaces.nextElement();
                Enumeration<InetAddress> addresses = ni.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    address = addresses.nextElement();
                    if (!address.isLoopbackAddress() && address.getHostAddress().indexOf(":") == -1) {
                        return address.getHostAddress();
                    }
                }
            }
            return null;
        } catch (Throwable t) {
            return null;
        }
    }

    private static int getNextId() {
        for (;;) {
            int current = count.get();
            int next = (current > 9000) ? 1000 : current + 1;
            if (count.compareAndSet(current, next))
                return next;
        }
    }
}
